package com.dc.docs._888_面试.concurrent._5_ccs;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

/**
 * Description: 倒计时门栓 CountDownLatch
 * 实例： 拼多多，一件商品至少需要两到三人拼团，商家才会发货。
 *
 * CountDownLatch 和 CyclicBarrier 的区别
 *  第一个区别
 *      倒计时门栓 CountDownLatch 一旦被打开后就不能再次合上，也是说只要被调用了足够次数的 countDown，await 方法就会失效，它是一次性的。
 *      CyclicBarrier 是循环发生的，当最后一个线程到达屏障，会优先重置屏障计数，屏障再次开启拦截阻隔。
 *  第二个区别
 *      CountDownLatch 是计数器, 线程来一个就记一个，此期间不阻塞线程，当达到指定数量之后才会去唤醒外部等待的线程，也就是说外部是有一个乃至多个线程等待一个条件满足之后才能继续执行，而这个条件就是满足一定数量的线程，这样才能激活当前外部线程的继续执行。
 *      CyclicBarrier 像一个栅栏，来一个线程阻塞一个，直到阻塞了指定数量的线程后，一次性全部激活，让他们同时执行，像一个百米冲刺一样。
 *
 *  https://juejin.im/post/5c53a1d1e51d45705b1a1728
 *
 * @author: gdc
 * @date: 2021/6/16
 * @version 1.0
 */
public class CountDownLatchDemo {

    public static void main(String[] args) throws InterruptedException {
        final int num = 7;
        CountDownLatch countDownLatch = new CountDownLatch(num);

        for (int i = 1; i <= num; i++) {
            new Thread(() -> {
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                System.out.println(Thread.currentThread().getName() + ", 已找到");
                countDownLatch.countDown();
            }, "龙珠" + i).start();
        }

        countDownLatch.await();
        System.out.println("开始召唤神龙...");
    }
}
